#include <expat.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
//#include <varargs.h>

#define FILE_MAX_LENGTH 1024*1024*20 //max 20mb

typedef struct ll{
	char* word;
	struct ll* next;
}List;
List* head=NULL;
List* last=NULL;

void print_list(List* l){
	int i=0;
	while(l!=NULL){
		printf("%s\t",l->word);
		l=l->next;
		i++;
	}
	printf("total word:%d",i);
}

void add_word(char* str){
	assert(str!=NULL);
	List* n=(List*)malloc(sizeof(List));
	n->word=str;
	n->next=NULL;
	last->next=n;
	last=n;
}

int Depth;
const char* TAG="k";
int process=0;

static void XMLCALL
character(void *data,const XML_Char* s,int len){
	if(!process)return;
	
	if(len==0 || (len==1 && s[0]=='\n'))return;
	char* buf=(char*)malloc(len+1);
	buf[len]='\0';
	memcpy(buf,s,len);
	add_word(buf);
	
	//printf("--data:\n%s\n--end\n",buf);
	//printf("%s\n",buf);
}

static void XMLCALL
start(void *data,const char *el, const char **attr){
	//printf("%s\n",el);
	/*
	if(strcmp(TAG,el)!=0 && !process){
		process=0;
		return;
	}else{
		process=1;
	}*/
	if(strcmp(TAG,el)!=0){
		process=0;
		return;
	}else{
		process=1;
		return;
	}
	
	int i;
	for(i=0;i<Depth;i++){
		printf("  ");
	}
	printf("--tag start:%s\n",el);
	//print attributes;
	if(attr[0]){
		printf("--begin attri:\n");
		for(i=0;attr[i];i+=2){
			printf(" %s=%s",attr[i],attr[i+1]);
		}
		printf("--end attri\n");
	}
	Depth++;
}

static void XMLCALL
end(void *data, const char *el){
	/*
	if(strcmp(TAG,el)!=0){
		process=0;
		return;
	}else{
		process=1;
	}*/
	process=0;
	return;
	
	int i;
	for(i=0;i<Depth;i++){
		printf("  ");
	}
	printf("--tag end:%s\n",el);
	Depth--;
}

int main(){
	head=(List*)malloc(sizeof(List));
	last=head;
	head->word="";
	
	char* buffer=malloc(FILE_MAX_LENGTH);
	assert(buffer!=NULL);
	
	char* file="/Users/Liq/op/google/data/oxford.xdxf";
	FILE* fp=fopen(file,"r");
	assert(fp!=NULL);
	char c;
	int i=0;
	int depth;
	
	while( (c=fgetc(fp))!=EOF && i<FILE_MAX_LENGTH){
		buffer[i]=c;
		i++;
	}
	buffer[i]='\0';
	printf("read length:%d\n",i);
	
	XML_Parser p=XML_ParserCreate(NULL);
	if(!p){
		fprintf(stderr,"create xml parser error\n");
		exit(-1);
	}
//	XML_SetUserData(parser,&depth);
	XML_SetCharacterDataHandler(p,character);
	XML_SetElementHandler(p,start,end);
	if(XML_Parse(p,buffer,i,0)==XML_STATUS_ERROR){
		fprintf(stderr,"parse error at line %d:%s\n",
			XML_GetCurrentLineNumber(p),
			XML_ErrorString(XML_GetErrorCode(p)));
		exit(-1);	
	}
	
	print_list(head);
	return 0;
}